// 表示对局的初始化信息
let gameInfo = {
    roomId: null,
    thisUserId: null,
    thatUserId: null,
    isWhite: true,
}

// 设定界面显示相关操作
function setScreenText(me) {
    let screen = document.querySelector('#screen');
    // 判断当前是谁落子
    if (me) {
        screen.innerHTML = "轮到你落子了!";
    } else {
        screen.innerHTML = "轮到对方落子了!";
    }
}

// 初始化 websocket
let websocketUrl = 'ws://' + location.host + '/game';
let websocket = new WebSocket(websocketUrl);
// 连接成功建立的回调方法
websocket.onopen = function() {
    console.log("连接房间成功!");
}
// 连接关闭的回调方法
websocket.onclose = function() {
    console.log("和游戏服务器断开连接!");
}
// 连接发生错误的回调方法
websocket.onerror = function() {
    console.log("和服务器的连接出现异常!");
    alert('和服务器连接断开! 返回游戏⼤厅!');
    location.assign('/game_hall.html');
}
// 监听页面关闭事件,在页面关闭之前,手动调用这里的 websocket 的 close 方法.
window.onbeforeunload = function() {
    websocket.close();
}

// 处理服务器返回的响应数据
websocket.onmessage = function(event) {
    console.log("[handlerGameReady] " + event.data);
    // JSON.parse 把 JSON 字符串转换成 JS 对象
    let resp = JSON.parse(event.data);

    if (!resp.ok) {
        alert("连接游戏失败! reason: " + resp.reason);
        // 如果出现连接失败的情况, 回到游戏大厅
        location.assign("/game_hall.html");
        return;
    }
    // 如果准备就绪,就进行对局的初始化
    if (resp.message == 'gameReady') {
        // 初始化对局信息
        gameInfo.roomId = resp.roomId;
        gameInfo.thisUserId = resp.thisUserId;
        gameInfo.thatUserId = resp.thatUserId;
        gameInfo.isWhite = (resp.whiteUser == resp.thisUserId);

        // 初始化棋盘
        initGame();

        // 初始化显示区域的内容
        setScreenText(gameInfo.isWhite);
    } else if (resp.message == 'repeatConnection') {
        alert("当前检测到多开! 请使用其他账号进行登录! ");
        location.assign("/login.html");
    }
}

// 初始化一局游戏
function initGame() {
    // 是我下还是对方下. 根据服务器分配的先后手情况决定
    let me = gameInfo.isWhite;
    // 游戏是否结束
    let over = false;
    let chessBoard = [];
    //初始化chessBord数组(表示棋盘的数组)
    for (let i = 0; i < 15; i++) {
        chessBoard[i] = [];
        for (let j = 0; j < 15; j++) {
            chessBoard[i][j] = 0;
        }
    }
    let chess = document.querySelector('#chess');
    let context = chess.getContext('2d');
    context.strokeStyle = "#BFBFBF";
    // 背景图片
    let logo = new Image();
    logo.src = "image/棋盘背景.png";
    logo.onload = function () {
        context.drawImage(logo, 0, 0, 450, 450);
        initChessBoard();
    }

    // 绘制棋盘网格
    function initChessBoard() {
        for (let i = 0; i < 15; i++) {
            context.moveTo(15 + i * 30, 15);
            context.lineTo(15 + i * 30, 430);
            context.stroke();
            context.moveTo(15, 15 + i * 30);
            context.lineTo(435, 15 + i * 30);
            context.stroke();
        }
    }

    // 绘制一个棋子, me 为 true
    function oneStep(i, j, isWhite) {
        context.beginPath();
        // 画一个弧线
        context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);
        context.closePath();
        var gradient = context.createRadialGradient(15 + i * 30 + 2, 15 + j * 30 - 2, 13, 15 + i * 30 + 2, 15 + j * 30 - 2, 0);
        // 根据 isWhite 来判断画的是黑子还是白子
        if (isWhite) {
            gradient.addColorStop(0, "#0A0A0A");
            gradient.addColorStop(1, "#636766");
        } else {
            gradient.addColorStop(0, "#D1D1D1");
            gradient.addColorStop(1, "#F9F9F9");
        }
        context.fillStyle = gradient;
        context.fill();
    }

    // 在棋盘点击落子, 就会触发这个方法
    chess.onclick = function (e) {
        // 如果点击操作超出范围, 或者当前不是我落子的回合
        // 就不会进行任何操作
        if (over) {
            return;
        }
        if (!me) {
            return;
        }
        // 设置落子的位置
        let x = e.offsetX;
        let y = e.offsetY;
        // 注意, 横坐标是列, 纵坐标是行
        // 这里做一个精确落子位置的操作, 使玩家点击落子后即使没有正好
        // 点到两线交点也可以很好的确定落子位置
        let col = Math.floor(x / 30);
        let row = Math.floor(y / 30);
        // 判断当前位置是否有棋子
        if (chessBoard[row][col] == 0) {
            // 发送坐标给服务器, 服务器要返回结果
            send(row, col);
        }
    }

    // 发送落子的请求
    function send(row, col) {
        // 根据前后端交互接口构造请求数据
        let req = {
            message: 'putChess',
            userId: gameInfo.thisUserId,
            row: row,
            col: col
        };
        // 使用 websocket 连接发送请求
        // 用 JSON.stringify 把请求构造成 JSON 字符串
        websocket.send(JSON.stringify(req))
    }

    // 之前 websocket.onmessage 主要是用来处理游戏就绪的响应, 在游戏就绪之后, 初始化完毕之后就不再有游戏就绪响应了
    // 所以就在这个 initGame 内部, 修改 websocket.onmessage 方法, 让这个方法里面针对落子
    websocket.onmessage = function(event) {
        console.log("[handlerGameReady] " + event.data);
        // JSON.parse 把 JSON 字符串转换成 JS 对象
        let resp = JSON.parse(event.data);
        if (resp.message != "putChess") {
            console.log("响应类型错误!");
            return;
        }

        // 先判定当前这个响应是自己落的子, 还是对方落的子
        if (resp.userId == gameInfo.thisUserId) {
            // 我自己落的子
            // 根据我自己子的颜色, 来绘制一个棋子
            oneStep(resp.col, resp.row, gameInfo.isWhite);
        } else if (resp.userId == gameInfo.thatUserId) {
            // 对手落的子
            oneStep(resp.col, resp.row, !gameInfo.isWhite);
        } else {
            // 响应错误! userId 有问题!
            console.log('[handlerPutChess] resp userId 错误!');
            return;
        }

        // 给对应的位置设为 1, 方便后续逻辑判定当前位置是否已经有子了
        chessBoard[resp.row][resp.col] = 1;

        // 交换双方的落子轮次
        me = !me;
        // 更改显示框的显示信息
        setScreenText(me);

        // 判定游戏是否结束
        let screenDiv = document.querySelector('#screen');
        if (resp.winner != 0) {
            // 根据玩家 Id 来判断是哪方获胜
            if (resp.winner == gameInfo.thisUserId) {
                screenDiv.innerHTML = '你赢了!';
            } else if (resp.winner == gameInfo.thatUserId) {
                screenDiv.innerHTML = '你输了!';
            } else {
                alert("winner 字段错误! " + resp.winner);
            }

            // 增加一个按钮, 让玩家点击之后, 再回到游戏大厅
            let backButton = document.createElement('button');
            backButton.innerHTML = '回到大厅';
            backButton.onclick = function() {
                // 防止浏览器回退造成不正确的结果
                // 这里使用 replace 进行跳转, 跳转之后就无法回退到当前页面了
                location.replace('/game_hall.html');
            }
            // 在 container div 下拼接按钮
            let fatherDiv = document.querySelector('.container>div');
            fatherDiv.appendChild(backButton);
        }
    }
}